import { Component, Fragment } from "react";
import global from "@/global/config.js"; //我感觉没有必要吧这个参数拆出来--不好复用
// antd
import {
  Form,
  Input,
  Button,
  Select,
  InputNumber,
  Radio,
  Row,
  Col,
} from "antd";
// propTypes
import PropTypes from "prop-types";

const { Option } = Select;
class FormCom extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mesPreix: {
        Input: "请输入",
        Radio: "请选择",
        Select: "请选择",
        Date: "请选择",
        Upload: "请上传",
        TextArea: "请输入",
      },
      isEdit: false,
    };
  }
  onFinish = (val) => {
    // 这个submit用来外面执行，外面将获得两个参数一个是表单的值，另一个是表单的dom用来重置表单用的
    this.props.submit(val, this.refs.form);
  };

  // 初始化
  initFormItem = () => {
    const { formItem } = this.props;
    // 检验是否存在
    if (!formItem || (formItem && formItem.length === 0)) {
      return;
    }
    // 定义变量
    const formList = [];
    // 循环处理
    formItem.forEach((item) => {
      item.type === "Input" && formList.push(this.inputElem(item));
      item.type === "Select" && formList.push(this.selectElem(item));
      item.type === "SelectComponent" &&
        formList.push(this.SelectComponent(item));
      item.type === "InputNumber" && formList.push(this.inputNumberElem(item));
      item.type === "Radio" && formList.push(this.radioElem(item));
      item.type === "Slot" && formList.push(this.slotElem(item));
      item.type === "Column" && formList.push(this.columnElem(item));
      item.type === "Date" && formList.push(this.dateElem(item));
      item.type === "Upload" && formList.push(this.uploadElem(item));
      item.type === "TextArea" && formList.push(this.textAreaElem(item));
    });
    return formList;
  };
  // 规则
  rules = (data) => {
    let rulesAry = [];
    const { required, message, rules, label, type } = data;
    const { mesPreix } = this.state;
    if (required) {
      let messages = message || `${mesPreix[type]}${label}`;
      rulesAry.push({ required: true, message: messages });
    }
    if (rules && rules.length > 0) {
      rulesAry = [...rulesAry, ...rules];
    }
    return rulesAry;
  };
  // 生命周期 -- 用于编辑
  componentWillReceiveProps({ editData }) {
    if (Object.keys(editData).length > 0) {
      this.refs.form.setFieldsValue(editData);
      this.setState({ isEdit: true });
    }
  }
  // 渲染
  inputElem = (data) => {
    const { label, name, style, placeholder } = data;
    const rules = this.rules(data);
    return (
      <Form.Item label={label} name={name} key={name} rules={rules}>
        <Input style={style} placeholder={placeholder} />
      </Form.Item>
    );
  };
  textAreaElem = (data) => {
    const { label, name, style, placeholder } = data;
    const rules = this.rules(data);
    return (
      <Form.Item label={label} name={name} key={name} rules={rules}>
        <Input.TextArea style={style} placeholder={placeholder} />
      </Form.Item>
    );
  };
  selectElem = (data) => {
    const { label, name, options, style, placeholder } = data;
    const rules = this.rules(data);
    return (
      <Form.Item label={label} name={name} key={name} rules={rules}>
        <Select style={style} placeholder={placeholder}>
          {options === "status" &&
            global[options].map((elem) => {
              const { value, label } = elem;
              return (
                <Option key={value} value={value}>
                  {label}
                </Option>
              );
            })}
        </Select>
      </Form.Item>
    );
  };
  inputNumberElem = (data) => {
    const { label, name, style, min, max } = data;
    const rules = this.rules(data);
    return (
      <Form.Item label={label} name={name} key={name} rules={rules}>
        <InputNumber min={min} max={max} style={style} />
      </Form.Item>
    );
  };
  radioElem = (data) => {
    const { label, name, options, style, placeholder } = data;
    const rules = this.rules(data);
    return (
      <Form.Item label={label} name={name} key={name} rules={rules}>
        <Radio.Group style={style} placeholder={placeholder}>
          {options &&
            options.map((elem) => {
              const { value, label } = elem;
              return (
                <Radio key={value} value={value}>
                  {label}
                </Radio>
              );
            })}
        </Radio.Group>
      </Form.Item>
    );
  };

  SelectComponent = () => {};
  slotElem = () => {};
  columnElem = () => {};
  dateElem = () => {};
  uploadElem = () => {};

  render() {
    const { formLayout, initialValues, isAddBtn, children } = this.props;
    const { isEdit } = this.state;
    return (
      <Fragment>
        <Row>
          <Col span={isAddBtn.leftRow}>
            <Form
              {...formLayout}
              onFinish={this.onFinish}
              ref="form"
              initialValues={initialValues}
              layout="inline"
            >
              {this.initFormItem()}
              <Form.Item>
                <Button htmlType="submit" type="primary">
                  {isEdit ? "修改" : "确定"}
                </Button>
              </Form.Item>
            </Form>
          </Col>
          <Col span={isAddBtn.rightRow}>
            {/* 通过插槽的方式显示 */}
            {children}
          </Col>
        </Row>
      </Fragment>
    );
  }
}
// formItem需要渲染的input formLayout布局 submit确定按钮  editData编辑的参数 initialValues初始值
//isAddBtn是否有新增按钮
// 校验数据类型
FormCom.propTypes = {
  editData: PropTypes.object,
  formLayout: PropTypes.object,
  formItem: PropTypes.array, //必传
  submit: PropTypes.func,
  initialValues: PropTypes.object,
  isAddBtn: PropTypes.object, //有插槽这个就必传 不然没位置
};
// 默认
FormCom.defaultProps = {
  editData: {},
  formLayout: {},
  formItem: {},
  initialValues: {},
  isAddBtn: {
    leftRow: 24,
    rightRow: 0, //总共24 不想要显示这个按钮 要么不传要么rightRow为0就行
  },
};
export default FormCom;
